using System;
using System.Collections.Generic;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using NntpClientLib;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace NewsgroupListSync
{
    [Guid("93cf3b24-b10a-4971-b165-65052412c989")]
    public class FeatureReceiver : SPFeatureReceiver
    {
        private string _jobName;
        public string jobName
        {
            get { return _jobName; }
            set { _jobName = value; }
        }

        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            using (SPWeb web = properties.Feature.Parent as SPWeb)
            {
                jobName = "Newsgroup Sync for " + web.Title;
                deleteJob(web, jobName);

                if (!listExists(web.Lists, "Newsgroups"))
                {
                    try
                    {
                        createMainNewsgroupList(web.Lists);
                        fillNewgroupList(web);
                    }
                    catch (ArgumentException ex)
                    {
                        throw new SPException("I had an issue making/filling the main list: " + ex.Message);
                    }
                }

                NewsgroupSyncJob ngsyncjob = new NewsgroupSyncJob(jobName, web.Site.WebApplication, web.Url);

                SPMinuteSchedule schedule = new SPMinuteSchedule();
                schedule.BeginSecond = 0;
                schedule.EndSecond = 59;
                schedule.Interval = 5;

                ngsyncjob.Schedule = schedule;
                ngsyncjob.Title = jobName;
                ngsyncjob.Update();
            }
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            using (SPWeb web = properties.Feature.Parent as SPWeb)
            {
                jobName = "Newsgroup Sync for " + web.Title;
                deleteJob(web, jobName);
            }
        }

        public override void FeatureInstalled(SPFeatureReceiverProperties properties) { /* no op */}

        public override void FeatureUninstalling(SPFeatureReceiverProperties properties) { /* no op */}

        private void deleteJob(SPWeb web, string jobname)
        {
            foreach (SPJobDefinition job in web.Site.WebApplication.JobDefinitions)
            {
                if (job.Name == jobname)
                {
                    job.Delete();
                }
            }
        }

        private void createMainNewsgroupList(SPListCollection collection)
        {
            try
            {
                Guid newNewsgroupID = collection.Add("Newsgroups", "A list of Newsgroups to sync goes here", SPListTemplateType.GenericList);

                SPList newsgroups = collection["Newsgroups"];

                newsgroups.EnableSyndication = true;
                newsgroups.OnQuickLaunch = true;
                newsgroups.ContentTypesEnabled = true;
                newsgroups.EnableAttachments = false;

                SPFieldCollection collFields = newsgroups.Fields;

                SPField title = collFields["Title"];
                title.Title = "NNTP Server";
                title.DefaultValue = "news.mathworks.com";
                title.Required = true;
                title.Update();


                string Newsgroup = "<Field Type=\"Text\" DisplayName=\"Newsgroup\" Name=\"Newsgroup\"/>";
                collFields.AddFieldAsXml(Newsgroup, true, SPAddFieldOptions.Default);
                SPField newsgroupField = collFields["Newsgroup"];
                newsgroupField.Required = true;
                newsgroupField.DefaultValue = "mw.test";
                newsgroupField.Update();

                string description = "<Field Type=\"Note\" DisplayName=\"Group Description\" Name=\"Group Description\"/>";
                collFields.AddFieldAsXml(description, true, SPAddFieldOptions.Default);
                SPField descriptionField = collFields["Group Description"];
                descriptionField.Required = true;
                descriptionField.DefaultValue = "This newsgroup is for...";
                descriptionField.Update();

                string LastIDSynced = "<Field Type=\"Integer\" DisplayName=\"Last Article Synced\" Name=\"Last Article Synced\"/>";
                collFields.AddFieldAsXml(LastIDSynced, true, SPAddFieldOptions.Default);
                SPField lastIDSyncedField = collFields["Last Article Synced"];
                lastIDSyncedField.Required = true;
                lastIDSyncedField.DefaultValue = "0";
                lastIDSyncedField.Update();

                newsgroups.Update();
            }
            catch (ArgumentException ex)
            {

                throw new SPException("I wasn't able to create that list for you because " + ex.Message);
            }

        }

        private void fillNewgroupList(SPWeb web)
        {
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                SPListItemCollection listItems = web.Lists["Newsgroups"].Items;
                client.Connect("news.mathworks.com");

                foreach (NewsgroupHeader header in client.RetrieveNewsgroups())
                {
                    string newsgroup = header.GroupName;
                    string description = getGroupDescription("news.mathworks.com", newsgroup);

                    if (!description.Contains("EXPIRES") && newsgroup.StartsWith("mw."))
                    {
                        SPListItem item = listItems.Add();
                        item["Title"] = "news.mathworks.com";
                        item["Newsgroup"] = newsgroup;
                        item["Last Article Synced"] = 0;
                        item["Group Description"] = description;
                        item.Update();
                    }
                }
                client.Close();
            }
        }

        private string getGroupDescription(string newsserver, string groupName)
        {
            string groupDesc = "";
            using (var client = new Rfc977NntpClientWithExtensions())
            {
                client.Connect(newsserver);
                client.SendSlave();
                client.SelectNewsgroup(groupName);
                IEnumerable<string> desc = client.RetrieveGroupDescriptions();
                foreach (string description in desc)
                {
                    groupDesc = (description);
                }
                client.Close();
            }
            return groupDesc.Replace(groupName, "").Trim();
        }

        private bool listExists(SPListCollection collection, string title)
        {
            foreach (SPList list in collection)
            {
                if (list.Title == title)
                {
                    return true;
                }
            }
            return false;
        }

        private SPServer getTimerServer(SPWeb web)
        {
            SPServerCollection servers = SPFarm.Local.Servers;
            SPServer appserver = null;
            if (web.Site.HostName == "sharepoint-test")
            {
                appserver = servers["sharepoint-test"];
            }
            else
            {
                appserver = servers["spfe-02-blr"];
            }
            return appserver;
        }
    }
}
